package com.hsmw.api.config.advice;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hsmw.api.exception.ApiException;
import com.htn.common.core.base.DataResponse;
import io.swagger.annotations.Api;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @author WD
 * @version 1.0
 * @description: TODO
 * @date 2021/1/26 15:23
 */
@RestControllerAdvice(basePackages = {"com.hsmw.api.controller"}) // 注意哦，这里要加上需要扫描的包
public class DataResponseControllerAdvice implements ResponseBodyAdvice<Object> {

	@Override
	public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> aClass) {
		// 如果接口返回的类型本身就是ResultVO那就没有必要进行额外的操作，返回false
		return !returnType.getParameterType().equals(DataResponse.class);
	}

	@Override
	public Object beforeBodyWrite(Object data, MethodParameter returnType, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
		// String类型不能直接包装，所以要进行些特别的处理
		if (returnType.getGenericParameterType().equals(String.class)) {
			ObjectMapper objectMapper = new ObjectMapper();
			try {
				// 将数据包装在ResultVO里后，再转换为json字符串响应给前端
				return objectMapper.writeValueAsString(new DataResponse<>(data));
			} catch (JsonProcessingException e) {
				throw new ApiException("返回String类型错误");
			}
		}
		// 将原本的数据包装在ResultVO里
		return new DataResponse<>(data);
	}
}
